#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
API路由模块
API Routes Module

定义所有的Web API端点和处理函数
"""

import logging
import time
import json
from flask import jsonify, request, Response

# 导入自定义异常类
from ..core.exceptions import (
    GimbalAngleOutOfRangeError,
    GimbalNotConnectedError,
    GimbalMoveError,
    GimbalControlError
)

logger = logging.getLogger("APIRoutes")


def register_api_routes(app, web_service):
    """
    注册API路由
    
    Args:
        app: Flask应用实例
        web_service: Web服务实例
    """
    
    @app.route('/api/faces', methods=['GET'])
    def get_faces():
        """获取人脸检测结果"""
        try:
            face_data = web_service.get_data_store().get_face_detection_data()
            return jsonify({
                'success': True,
                'data': face_data,
                'timestamp': time.time()
            })
        except Exception as e:
            logger.error(f"获取人脸数据失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e),
                'timestamp': time.time()
            }), 500
    
    @app.route('/api/gimbal/control', methods=['POST'])
    def control_gimbal():
        """控制云台到指定角度"""
        try:
            data = request.get_json()
            if not data:
                return jsonify({
                    'success': False,
                    'error': '缺少请求数据'
                }), 400

            pan = data.get('pan')
            tilt = data.get('tilt')

            if pan is None or tilt is None:
                return jsonify({
                    'success': False,
                    'error': '缺少pan或tilt参数'
                }), 400

            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({
                    'success': False,
                    'error': '云台控制器未初始化'
                }), 503

            success = gimbal.move_to_angle(float(pan), float(tilt))
            if success:
                return jsonify({
                    'success': True,
                    'message': f'云台已移动到 Pan={pan}°, Tilt={tilt}°',
                    'angles': {'pan': pan, 'tilt': tilt}
                })
            else:
                return jsonify({
                    'success': False,
                    'error': '云台移动失败'
                }), 500

        except GimbalAngleOutOfRangeError as e:
            # 角度超出范围的具体错误
            logger.warning(f"云台角度超出范围: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 400

        except GimbalNotConnectedError as e:
            # 云台未连接错误
            logger.warning(f"云台未连接: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 503

        except GimbalMoveError as e:
            # 云台移动失败错误
            logger.error(f"云台移动失败: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 500

        except Exception as e:
            logger.error(f"云台控制失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/gimbal/move_relative', methods=['POST'])
    def move_gimbal_relative():
        """相对移动云台"""
        try:
            data = request.get_json()
            if not data:
                return jsonify({
                    'success': False,
                    'error': '缺少请求数据'
                }), 400

            pan_delta = data.get('pan_delta', 0)
            tilt_delta = data.get('tilt_delta', 0)

            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({
                    'success': False,
                    'error': '云台控制器未初始化'
                }), 503

            success = gimbal.move_relative(float(pan_delta), float(tilt_delta))
            if success:
                current_pan, current_tilt = gimbal.get_current_angles()
                return jsonify({
                    'success': True,
                    'message': f'云台相对移动 Pan={pan_delta:+.1f}°, Tilt={tilt_delta:+.1f}°',
                    'current_angles': {'pan': current_pan, 'tilt': current_tilt}
                })
            else:
                return jsonify({
                    'success': False,
                    'error': '云台相对移动失败'
                }), 500

        except GimbalAngleOutOfRangeError as e:
            # 角度超出范围的具体错误
            logger.warning(f"云台相对移动角度超出范围: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 400

        except GimbalNotConnectedError as e:
            # 云台未连接错误
            logger.warning(f"云台未连接: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 503

        except GimbalMoveError as e:
            # 云台移动失败错误
            logger.error(f"云台相对移动失败: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 500

        except Exception as e:
            logger.error(f"云台相对移动失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/gimbal/status', methods=['GET'])
    def get_gimbal_status():
        """获取云台状态"""
        try:
            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({
                    'success': False,
                    'error': '云台控制器未初始化'
                }), 503
            
            status = gimbal.get_status()
            return jsonify({
                'success': True,
                'data': status,
                'timestamp': time.time()
            })
            
        except Exception as e:
            logger.error(f"获取云台状态失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/gimbal/reset', methods=['POST'])
    def reset_gimbal():
        """重置云台位置"""
        try:
            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({
                    'success': False,
                    'error': '云台控制器未初始化'
                }), 503

            success = gimbal.reset_position()
            if success:
                current_pan, current_tilt = gimbal.get_current_angles()
                return jsonify({
                    'success': True,
                    'message': f'云台位置已重置为 Pan={current_pan}°, Tilt={current_tilt}°',
                    'angles': {'pan': current_pan, 'tilt': current_tilt}
                })
            else:
                return jsonify({
                    'success': False,
                    'error': '云台重置失败'
                }), 500

        except GimbalAngleOutOfRangeError as e:
            # 角度超出范围的具体错误
            logger.warning(f"云台重置角度超出范围: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 400

        except GimbalNotConnectedError as e:
            # 云台未连接错误
            logger.warning(f"云台未连接: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 503

        except GimbalMoveError as e:
            # 云台移动失败错误
            logger.error(f"云台重置失败: {e}")
            return jsonify({
                'success': False,
                **e.to_dict()
            }), 500

        except Exception as e:
            logger.error(f"云台重置失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/tracking/start', methods=['POST'])
    def start_tracking():
        """启动人脸追踪"""
        try:
            data = request.get_json() or {}
            target_id = data.get('target_id')
            
            success = web_service.start_tracking(target_id)
            if success:
                return jsonify({
                    'success': True,
                    'message': '人脸追踪已启动',
                    'target_id': target_id
                })
            else:
                return jsonify({
                    'success': False,
                    'error': '启动人脸追踪失败'
                }), 500
                
        except Exception as e:
            logger.error(f"启动追踪失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/tracking/stop', methods=['POST'])
    def stop_tracking():
        """停止人脸追踪"""
        try:
            success = web_service.stop_tracking()
            if success:
                return jsonify({
                    'success': True,
                    'message': '人脸追踪已停止'
                })
            else:
                return jsonify({
                    'success': False,
                    'error': '停止人脸追踪失败'
                }), 500
                
        except Exception as e:
            logger.error(f"停止追踪失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/status', methods=['GET'])
    def get_system_status():
        """获取系统状态"""
        try:
            all_data = web_service.get_data_store().get_all_data()
            
            # 添加应用信息
            all_data['app_info'] = {
                'name': web_service.config.app_name,
                'version': web_service.config.version,
                'environment': web_service.config.environment
            }
            
            return jsonify({
                'success': True,
                'data': all_data,
                'timestamp': time.time()
            })
            
        except Exception as e:
            logger.error(f"获取系统状态失败: {e}")
            return jsonify({
                'success': False,
                'error': str(e)
            }), 500
    
    @app.route('/api/health', methods=['GET'])
    def health_check():
        """系统健康检查"""
        try:
            # 检查摄像头状态
            camera_status = "connected" if (web_service.camera and web_service.camera.isOpened()) else "disconnected"
            
            # 检查云台状态
            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                gimbal_status = "disabled"
            elif gimbal.connected:
                gimbal_status = "connected"
            else:
                gimbal_status = "disconnected"
            
            # 检查最新检测结果
            face_data = web_service.get_data_store().get_face_detection_data()
            detection_age = time.time() - face_data.get('timestamp', 0)
            detection_status = "active" if detection_age < 5.0 else "stale"
            
            # 系统整体状态
            overall_status = "healthy" if (
                camera_status == "connected" and 
                detection_status == "active" and
                gimbal_status in ["connected", "disabled"]
            ) else "unhealthy"
            
            return jsonify({
                'success': True,
                'status': overall_status,
                'timestamp': time.time(),
                'components': {
                    'camera': camera_status,
                    'gimbal': gimbal_status,
                    'detection': detection_status,
                    'face_count': face_data.get('face_count', 0),
                    'tracking_enabled': web_service.tracking_enabled
                }
            })
            
        except Exception as e:
            logger.error(f"健康检查失败: {e}")
            return jsonify({
                'success': False,
                'status': 'error',
                'error': str(e),
                'timestamp': time.time()
            }), 500

    # 添加原有Web界面需要的API端点

    @app.route('/move_servo', methods=['POST'])
    def move_servo():
        """移动舵机到指定角度（原有Web界面兼容）"""
        try:
            data = request.get_json()
            logger.debug(f"收到move_servo请求: {data}")

            if not data:
                return jsonify({'success': False, 'message': '缺少请求数据'}), 400

            pin = data.get('pin')
            angle = data.get('angle')

            if pin is None or angle is None:
                logger.warning(f"缺少参数: pin={pin}, angle={angle}, 原始数据: {data}")
                return jsonify({'success': False, 'message': '缺少pin或angle参数'}), 400

            # 转换数据类型
            try:
                pin = int(pin)
                angle = float(angle)
            except (ValueError, TypeError) as e:
                logger.error(f"参数类型转换失败: pin={pin}, angle={angle}, error={e}")
                return jsonify({'success': False, 'message': '参数类型错误'}), 400

            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({'success': False, 'message': '舵机控制功能已禁用'})

            # 根据pin确定是pan还是tilt
            current_pan, current_tilt = gimbal.get_current_angles()

            logger.debug(f"当前角度: pan={current_pan}, tilt={current_tilt}")
            logger.debug(f"配置引脚: pan_pin={web_service.config.gimbal.pan_pin}, tilt_pin={web_service.config.gimbal.tilt_pin}")

            if pin == web_service.config.gimbal.pan_pin:
                success = gimbal.move_to_angle(angle, current_tilt)  # 只移动pan
                axis = 'pan'
            elif pin == web_service.config.gimbal.tilt_pin:
                success = gimbal.move_to_angle(current_pan, angle)  # 只移动tilt
                axis = 'tilt'
            else:
                logger.warning(f"无效的舵机引脚: {pin}, 期望: {web_service.config.gimbal.pan_pin} 或 {web_service.config.gimbal.tilt_pin}")
                return jsonify({'success': False, 'message': f'无效的舵机引脚: {pin}'})

            if success:
                logger.info(f"舵机移动成功: {axis}={angle}°")
                return jsonify({'success': True, 'message': f'舵机 {pin} ({axis}) 已移动到 {angle} 度'})
            else:
                logger.error(f"舵机移动失败: {axis}={angle}°")
                return jsonify({'success': False, 'message': '舵机控制失败'})

        except Exception as e:
            logger.error(f"移动舵机异常: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500

    @app.route('/get_servo_angles', methods=['GET'])
    def get_servo_angles():
        """获取当前舵机角度"""
        try:
            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({'success': False, 'message': '舵机控制功能已禁用'})

            pan, tilt = gimbal.get_current_angles()
            return jsonify({
                'success': True,
                'angles': {
                    'pan': round(pan, 1),
                    'tilt': round(tilt, 1)
                }
            })

        except Exception as e:
            logger.error(f"获取舵机角度失败: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500

    @app.route('/move_servo_relative', methods=['POST'])
    def move_servo_relative():
        """相对移动舵机（原有Web界面兼容）"""
        try:
            data = request.get_json()
            if not data:
                return jsonify({'success': False, 'message': '缺少请求数据'}), 400

            axis = data.get('axis')
            delta = data.get('delta')

            if axis is None or delta is None:
                return jsonify({'success': False, 'message': '缺少axis或delta参数'}), 400

            if axis not in ['pan', 'tilt']:
                return jsonify({'success': False, 'message': '无效的舵机轴 (需要 "pan" 或 "tilt")'})

            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({'success': False, 'message': '舵机控制功能已禁用'})

            # 执行相对移动
            if axis == 'pan':
                success = gimbal.move_relative(float(delta), 0)
            else:
                success = gimbal.move_relative(0, float(delta))

            if success:
                current_pan, current_tilt = gimbal.get_current_angles()
                current_angle = current_pan if axis == 'pan' else current_tilt
                return jsonify({
                    'success': True,
                    'message': f'{axis.capitalize()} 舵机移动 {delta:+.1f} 度到 {current_angle:.1f} 度'
                })
            else:
                return jsonify({'success': False, 'message': '舵机控制失败'})

        except Exception as e:
            logger.error(f"相对移动舵机失败: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500

    @app.route('/get_detection_status', methods=['GET'])
    def get_detection_status():
        """获取人脸检测状态（原有Web界面兼容）"""
        try:
            face_data = web_service.get_data_store().get_face_detection_data()
            face_detected = face_data.get('face_count', 0) > 0
            timestamp = face_data.get('timestamp', 0)
            is_fresh = (time.time() - timestamp) < 5.0

            return jsonify({
                'success': True,
                'detection_status': {
                    'face_detected': face_detected,
                    'timestamp': timestamp,
                    'is_fresh': is_fresh
                }
            })

        except Exception as e:
            logger.error(f"获取检测状态失败: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500

    @app.route('/get_face_count', methods=['GET'])
    def get_face_count():
        """获取人脸数量"""
        try:
            face_data = web_service.get_data_store().get_face_detection_data()
            face_count = face_data.get('face_count', 0)
            timestamp = face_data.get('timestamp', 0)
            is_fresh = (time.time() - timestamp) < 5.0

            return jsonify({
                'success': True,
                'face_count': face_count,
                'face_detected': face_count > 0,
                'timestamp': timestamp,
                'is_fresh': is_fresh
            })

        except Exception as e:
            logger.error(f"获取人脸数量失败: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500

    @app.route('/reset_position', methods=['POST'])
    def reset_position():
        """重置舵机位置（原有Web界面兼容）"""
        try:
            gimbal = web_service.get_gimbal_controller()
            if not gimbal:
                return jsonify({'success': False, 'message': '舵机控制功能已禁用'})

            success = gimbal.reset_position()
            if success:
                current_pan, current_tilt = gimbal.get_current_angles()
                return jsonify({
                    'success': True,
                    'message': f'舵机位置已重置为 Pan={current_pan:.1f}, Tilt={current_tilt:.1f}'
                })
            else:
                return jsonify({'success': False, 'message': '舵机重置失败'})

        except Exception as e:
            logger.error(f"重置舵机位置失败: {e}")
            return jsonify({'success': False, 'message': str(e)}), 500



    @app.route('/toggle_tracking', methods=['POST'])
    def toggle_tracking():
        """切换追踪状态（原有Web界面兼容）"""
        try:
            data = request.get_json() or {}
            enabled_req = data.get('enabled')

            current_enabled = web_service.tracking_enabled

            # 确定目标状态
            if enabled_req is None:
                target_enabled = not current_enabled
            else:
                target_enabled = bool(enabled_req)

            # 检查是否需要改变状态
            if target_enabled == current_enabled:
                status_str = "已启动" if current_enabled else "已停止"
                return jsonify({
                    'success': True,
                    'message': f'自动跟踪{status_str}',
                    'state': current_enabled
                })

            # 执行状态切换
            if target_enabled:
                success = web_service.start_tracking()
                if success:
                    return jsonify({
                        'success': True,
                        'message': '自动跟踪已启动',
                        'state': True
                    })
                else:
                    return jsonify({
                        'success': False,
                        'message': '启动自动跟踪失败',
                        'state': False
                    })
            else:
                success = web_service.stop_tracking()
                if success:
                    return jsonify({
                        'success': True,
                        'message': '自动跟踪已停止',
                        'state': False
                    })
                else:
                    return jsonify({
                        'success': False,
                        'message': '停止自动跟踪失败',
                        'state': True
                    })

        except Exception as e:
            logger.error(f"切换追踪状态失败: {e}")
            return jsonify({
                'success': False,
                'message': str(e),
                'state': web_service.tracking_enabled
            }), 500
